<?php

namespace Illuminate\Auth;

use InvalidArgumentException;

/**
 * 创建用户提供者工具类
 */
trait CreatesUserProviders
{
    /**
     * 自定义的用户提供者创建器
     *
     * @var array
     */
    protected $customProviderCreators = [];

    /**
     * 创建用户提供者
     *
     * @param  string|null $provider 名称
     * @return \Illuminate\Contracts\Auth\UserProvider|null
     *
     * @throws \InvalidArgumentException
     */
    public function createUserProvider($provider = null)
    {
        if (is_null($config = $this->getProviderConfiguration($provider))) {
            return;
        }

        // 用户自定义的 UserProvider 驱动程序创建
        if (isset($this->customProviderCreators[$driver = ($config['driver'] ?? null)])) {
            return call_user_func(
                $this->customProviderCreators[$driver], $this->app, $config
            );
        }

        switch ($driver) {
            case 'database':
                return $this->createDatabaseProvider($config);
            case 'eloquent':
                return $this->createEloquentProvider($config);
            default:
                throw new InvalidArgumentException(
                    "Authentication user provider [{$driver}] is not defined."
                );
        }
    }

    /**
     * 获取指定用户提供者配置数据
     *
     * @param  string|null $provider 提供者名称
     * @return array|null 配置项
     */
    protected function getProviderConfiguration($provider)
    {
        if ($provider = $provider ?: $this->getDefaultUserProvider()) {
            return $this->app['config']['auth.providers.' . $provider];
        }
    }

    /**
     * 创建基于 database 的用户提供者实例
     *
     * @param  array $config 配置项
     * @return \Illuminate\Auth\DatabaseUserProvider
     */
    protected function createDatabaseProvider($config)
    {
        $connection = $this->app['db']->connection($config['connection'] ?? null);

        return new DatabaseUserProvider($connection, $this->app['hash'], $config['table']);
    }

    /**
     * 创建基于 Eloquent 的用户提供者实例
     *
     * @param  array $config 配置项
     * @return \Illuminate\Auth\EloquentUserProvider
     */
    protected function createEloquentProvider($config)
    {
        return new EloquentUserProvider($this->app['hash'], $config['model']);
    }

    /**
     * 获取默认的用户提供者名称
     *
     * @return string
     */
    public function getDefaultUserProvider()
    {
        return $this->app['config']['auth.defaults.provider'];
    }
}
